home *** CD-ROM | disk | FTP | other *** search
Java Source | 2000-07-26 | 6.9 KB | 250 lines |
-
- package applets;
-
- import shout3d.*;
- import shout3d.core.*;
- import shout3d.math.*;
- import custom_nodes.*; //for ScanTheSkiesDisplay
- import java.applet.*; //for AudioClip
-
-
- public class ScanTheSkiesPanel extends Shout3DPanel implements DeviceObserver {
-
-
-
- //game state variables
- boolean started = false;
- boolean killed = false;
-
-
- //screen pixels
- int startPixelX;
- int startPixelY;
-
- //heads-Up display
- ScanTheSkiesDisplay display;
- int score = 0;
- double startTime;
- int elapsedSeconds;
-
- //missile
- int totalSeconds = 40;
- float distance;
- float speed = 10; //10 meters per second
- float startDistance = 10.f * totalSeconds;
- Transform child;
- Transform parent;
- float[] missileAxisAngle = new float[4];
- float[] missileEulers = new float[3];
- Quaternion missileQ = new Quaternion();
-
- //gun
- Transform gun;
- float[] gunAxisAngle = new float[4];
- float[] gunEulers = new float[3];
- Quaternion gunQ = new Quaternion();
- float headingSpeed = 0.0f;
- float pitchSpeed = 0.0f;
- Picker fire;
-
- //animated explosion
- TimeSensor detonator;
- Transform explosion;
- float [] intersection = new float[3];
- AudioClip gong;
-
-
-
-
- //the constructor
- public ScanTheSkiesPanel (Shout3DApplet applet){
- super(applet);
- }
-
-
- public void customInitialize() {
-
- //get references to scene nodes
- child = (Transform) getNodeByName("CHILD");
- parent = (Transform) getNodeByName("PARENT");
- detonator = (TimeSensor) getNodeByName("DETONATOR");
- gun = (Transform) getNodeByName("GUN");
- explosion = (Transform) getNodeByName("EXPLOSION");
- display = (ScanTheSkiesDisplay) getNodeByName("DISPLAY");
- gong = applet.getAudioClip(applet.getCodeBase(), "models/sounds/gong.au");
-
- //register observers
- addDeviceObserver(this, "MouseInput", null);
- getRenderer().addRenderObserver(this, null);
-
- //create a picker
- fire = getNewPicker();
-
- }
-
-
-
- protected void finalize() {
- removeDeviceObserver(this,"MouseInput");
- getRenderer().removeRenderObserver(this);
- }
-
-
-
- public boolean onDeviceInput(DeviceInput di, Object userData) {
-
- MouseInput mi = (MouseInput) di;
- switch (mi.which) {
-
- case MouseInput.DOWN:
-
- if (started == false) {
- //create missile to start
- started = true;
- newMissile();
- }
-
- if (killed) {
- //if killed, reset score
- score = 0;
- display.score.setValue(score);
- killed = false;
- }
-
- //in any case, store start of drag
- startPixelX = mi.x;
- startPixelY = mi.y;
- return true;
-
- case MouseInput.DRAG:
-
- //set gun rotation speeds
- //based on drag distances
- int endPixelX = mi.x;
- int endPixelY = mi.y;
- int dragDistanceX = endPixelX - startPixelX;
- int dragDistanceY = endPixelY - startPixelY;
- headingSpeed = dragDistanceX/150f;
- pitchSpeed = dragDistanceY/70f;
- return true;
-
-
- case MouseInput.UP:
-
- //store intersection point
- fire.setPickInfo(Picker.POINT, true);
-
- //compute center of window
- int centerPixelX = size().width/2;
- int centerPixelY = size().height/2;
-
- //fire the picker ray
- Node [] results = fire.pickClosest(centerPixelX, centerPixelY);
-
- //if ray hits something
- if (results != null) {
-
- //move explosion to intersection
- //and detonate with sound
- intersection = fire.getPickInfo(Picker.POINT);
- explosion.translation.setValue(intersection);
- detonator.start();
- gong.play();
-
- //increment the score
- //and update the display
- score++;
- display.score.setValue(score);
-
- //decrease missle start
- //distance by 10, but not
- //below 200 meters
- if (totalSeconds > 20) {
- totalSeconds--;
- startDistance = 10.0f * totalSeconds;
- }
-
- //launch a new missile
- newMissile();
- }
-
- //stop gun rotation
- headingSpeed = 0.0f;
- pitchSpeed = 0.0f;
- return true;
-
-
- }//end of switch
-
- return false;
-
- }//end of onDeviceInput()
-
-
-
-
- public void onPreRender (Renderer r, Object o) {
-
- //do nothing unless game is started
- if (started) {
-
- //compute current distance
- //of missile from player
- float delta = speed/getFramesPerSecond();
- distance = distance - delta;
-
- //end game if missile hits player
- if (distance <= 0){
-
- display.shotClock.setValue(0);
- killed = true;
- started = false;
- totalSeconds = 40;
- startDistance = 10.0f * totalSeconds;
- return;
- }
-
- //if missile still moving,
- //update its position
- child.translation.set1Value(2, -distance);
-
- //update gun rotation
- float headingDelta = headingSpeed/getFramesPerSecond();
- float pitchDelta = pitchSpeed/getFramesPerSecond();
- gunEulers[0] = gunEulers[0] + headingDelta;
- gunEulers[1] = gunEulers[1] + pitchDelta;
- gunQ.setEulers(gunEulers);
- gunQ.getAxisAngle(gunAxisAngle);
- gun.rotation.setValue(gunAxisAngle);
-
- //update shot clock
- double currentTime = getAbsoluteTime();
- elapsedSeconds = (int)(currentTime - startTime);
- display.shotClock.setValue(totalSeconds - elapsedSeconds);
-
-
- }//end of if started
-
- }//end of onPreRender()
-
-
- private void newMissile() {
-
- //set random heading and pitch
- missileEulers[0] = (float) (Math.random() * 6.28);
- missileEulers[1] = (float) (Math.random() * 6.28);
- missileQ.setEulers(missileEulers);
-
- //rotate missile to start position
- missileQ.getAxisAngle(missileAxisAngle);
- parent.rotation.setValue(missileAxisAngle);
- distance = startDistance;
- child.translation.set1Value(2, -distance);
-
- //reset clock
- startTime = getAbsoluteTime();
-
- }//end of newMissile()
-
-
- } //end of class